import path from 'path';

import { expect } from '@jest/globals';
import execa from 'execa';
import fse from 'fs-extra';

import { getJson5Obj } from '../../../../src/utils/json-util.js';

// @ts-ignore
import { runHvigorAsync } from '../../common/common.ts';
// @ts-ignore
import { commonConfig } from '../../plugins/common-config.ts';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel, CURRENT_HMOS_API,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: CURRENT_HMOS_API,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility
  },
  modulesOption: {
    [ModuleTemplateType.StaticLibrary]: 1
  }
};

/**
 *
 * @param {Project} project
 * @param {TestTaskOption} taskConfig
 * @param {ICaseRecord} record
 * @return res
 */
const testfun: TestCaseFun = async (project, taskConfig, record) => {
  const projectRootPath = project.projectRootPath();
  const entryModulePath = path.resolve(projectRootPath, 'entry');
  const harModulePath = path.resolve(projectRootPath, 'staticLibrary');

  // 改造成字节码har
  const harBuildProfilePath = path.resolve(harModulePath, 'build-profile.json5');
  const projectBuildProfilePath = path.resolve(projectRootPath, 'build-profile.json5');
  const harBuildProfileContetnt =  getJson5Obj(harBuildProfilePath);
  const projectBuildProfileContetnt = getJson5Obj(projectBuildProfilePath);
  harBuildProfileContetnt.buildOption = {
    'arkOptions': {
      'byteCodeHar': true
    }
  };
  projectBuildProfileContetnt.app.products[0].buildOption =  {
    'strictMode': {
      'caseSensitiveCheck': true,
      'useNormalizedOHMUrl': true
    }
  };
  fse.writeJSONSync(harBuildProfilePath, harBuildProfileContetnt);
  fse.writeJSONSync(projectBuildProfilePath, projectBuildProfileContetnt);


  // har的MainPage.ets 加 export class Blog { init() {}}
  const harMagePagePath = path.resolve(harModulePath, 'src/main/ets/components/MainPage.ets');
  let harMainPageContent = fse.readFileSync(harMagePagePath).toString();
  harMainPageContent += 'export class Blog { init() {}}';
  fse.writeFileSync(harMagePagePath, harMainPageContent);

  // har的Index.ets 加 export { Blog } from './src/main/ets/components/MainPage'
  const harIndexPath = path.resolve(harModulePath, 'Index.ets');
  let harIndexContent = fse.readFileSync(harIndexPath).toString();
  harIndexContent += 'export { Blog } from \'./src/main/ets/components/MainPage\'';
  fse.writeFileSync(harIndexPath, harIndexContent);

  const harCommonCommand = [
    'assembleHar',
    '--no-daemon'
  ];

  // 生成har1.har并放到entry目录
  const result = await runHvigorAsync(project.projectRootPath(), harCommonCommand);
  expect(result.stdout).toContain('BUILD SUCCESSFUL');
  const outputHarPath = path.resolve(harModulePath, 'build/default/outputs/default/staticLibrary.har');
  fse.copyFileSync(outputHarPath, path.resolve(entryModulePath, 'har1.har'));

  // 修改har里的version
  const harOhPackageJson5Path = path.resolve(harModulePath, 'oh-package.json5');
  const harOhPackageJson5 = getJson5Obj(harOhPackageJson5Path);
  harOhPackageJson5.version = '1.0.1';
  fse.writeJSONSync(harOhPackageJson5Path, harOhPackageJson5);

  await runHvigorAsync(project.projectRootPath(), [
    '--sync',
    '--no-daemon'
  ]);

  // 生成har2.har并放到entry目录
  const result1 = await runHvigorAsync(project.projectRootPath(), harCommonCommand);
  expect(result1.stdout).toContain('BUILD SUCCESSFUL');
  fse.copyFileSync(outputHarPath, path.resolve(entryModulePath, 'har2.har'));

  // entry依赖har1.har
  const entryOhPackageJson5Path = path.resolve(entryModulePath, 'oh-package.json5');
  let entryOhPackageJson5 = getJson5Obj(entryOhPackageJson5Path);
  entryOhPackageJson5.dependencies = {
    'staticLibrary': 'file:./har1.har'
  };
  fse.writeJSONSync(entryOhPackageJson5Path, entryOhPackageJson5);

  // 执行ohpm install
  let install = await execa.command(commonConfig.ohpmInstallCommand, {
    cwd: entryModulePath
  });
  record.addStep('entry install', install);

  // entry的Pages下的Index.ets 加 import {Blog} from "har"; const a = Blog;
  const entryPagesIndexPath = path.resolve(entryModulePath, 'src/main/ets/pages/Index.ets');
  let entryPagesIndexContent = fse.readFileSync(entryPagesIndexPath).toString();
  entryPagesIndexContent = `import {Blog} from "staticLibrary"; const a: Object = Blog;\n${entryPagesIndexContent}`;
  fse.writeFileSync(entryPagesIndexPath, entryPagesIndexContent);

  const entryCommonCommand = [
    'assembleHap',
    '--no-daemon'
  ];

  // 构建entry,检查中间产物的版本号1.0.0
  const result3 = await runHvigorAsync(project.projectRootPath(), entryCommonCommand);
  expect(result3.stdout).toContain('BUILD SUCCESSFUL');
  const cacheIndexPath = path.resolve(entryModulePath, 'build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/Index.ts');
  let cacheIndexContent = fse.readFileSync(cacheIndexPath).toString();
  expect(cacheIndexContent).toContain('staticLibrary/Index&1.0.0');

  // entry依赖har2.har
  entryOhPackageJson5 = getJson5Obj(entryOhPackageJson5Path);
  entryOhPackageJson5.dependencies = {
    'staticLibrary': 'file:./har2.har'
  };
  fse.writeJSONSync(entryOhPackageJson5Path, entryOhPackageJson5);

  // 执行ohpm install
  install = await execa.command(commonConfig.ohpmInstallCommand, {
    cwd: entryModulePath
  });
  record.addStep('entry install', install);

  // 构建entry,检查中间产物的版本号1.0.1
  const result4 = await runHvigorAsync(project.projectRootPath(), entryCommonCommand);
  expect(result4.stdout).toContain('BUILD SUCCESSFUL');
  cacheIndexContent = fse.readFileSync(cacheIndexPath).toString();
  expect(cacheIndexContent).toContain('staticLibrary/Index&1.0.1');
};

TestCaseBuilder.builder()
  .caseName('DTS2024093012963')
  // eslint-disable-next-line max-len
  .description('【DTSE】【应用：哔哩哔哩】【HOS单框架】【API 11】【win/mac】【IssueReport单号：240925171326088】【概率：必现】在oh-package.json5中的overrides中修改依赖的版本号，sync之后重新推包到手机会crash，报错日志为cannot find record\'上一个依赖的版本号\'')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.DTS).build())
  .testFun(testfun)
  .load();
